/*
 * About Segments And Rooms:
 * A segment consists of one or more rooms of particular importance to
 * the gameplay. Note: right now, a segment has exactly one room.
 * The rooms contain treasures, monsters, puzzles etc.
 * A room has a number of entrances and a number of exits ranging from
 * 1 to MAX_ENTRANCES/MAX_EXITS. Thus, whole segments are also limited
 * to this amount of entrances and exits, which are called "paths".
 * The dungeon generator (caller) dictates the number of entrances and
 * exits. The segment generator code must accomodate these numbers or
 * impose design-time restrictions with assert(0).
 * One easy way for the dungeon generator to provide acceptable paths
 * is to simply append or prepend a CORRIDOR-Segment to join or fork
 * them.
 */

#ifndef __SEGMENT_H_
#define __SEGMENT_H_

#include "generator.h"
#include "layout.h"
#include "world/map.h"

#define MAX_ROOMS 4

typedef enum {
	ST_SPAWN,       // player start point
	ST_CORRIDOR,    // unobstrusive pass-through corridor
	ST_MULTIPLEXER, // joins and splits paths without leaving choice to the player
	ST_SHORTCUT,    // conditional corridor, opens a path once a more advanced path has been visited
	ST_TREASURE,    // free treasure up for grabs
	ST_MONSTERS,    // fight monsters for treasure & exit
	ST_BOSS,        // fight boss monster for treasure & exit
	ST_SWITCHES,    // flip switches for treasure & exit
	ST_SOKOBAN,     // move boxes for treasure & exit
	ST_MULTIPLAYER, // get help from fellow players for treasure or take the exit for free
	ST_GOAL         // first player to enter this room wins the game
} SegmentTypeId;

struct Segment_t;

typedef void (*RoomLayoutGenerator) (struct Segment_t* segment, Layout* layout, Generator* generator);
typedef void (*RoomContentGenerator) (struct Segment_t* segment, Layout* layout, Map* map,
	Coord* entry, int n_entries, Coord* exit, int n_exits);
	
typedef struct {
	SegmentTypeId id;
	const char* name;
	int min_roots;    // roots are paths which lead into this segment
	int max_roots;
	int min_branches; // branches are paths which lead out of this segment
	int max_branches;
	int min_rooms;
	int max_rooms;
	RoomLayoutGenerator layout_generator;
	RoomContentGenerator content_generator;
} SegmentType;

extern SegmentType SEGTYPE [11]; // for each SegmentTypeId

typedef struct Segment_t {
	SegmentType* type;
	int intensity;
	struct Segment_t* root [MAX_ROOTS];
	int n_roots;
	struct Segment_t* branch [MAX_BRANCHES];
	int n_branches;
	
	// Room convention: room[0] is segment exit room, room[1] is entry.
	// If n_rooms == 1, room[0] is both.
	int room [MAX_ROOMS];
	int n_rooms;
} Segment;

void segment_generate (Segment* s, SegmentTypeId t, int intensity);
void segment_make_support_corridor (Segment* s, int n_roots, int n_branches);
void segment_make_goal (Segment* s, int n_roots);
void segment_plant_obstacles (Map* map, Coord* coord, int n_coords);

#endif 
